export class WebFileReader {
    private chunkDatas: string[] = []; // buffer to store reading data

    constructor(
        public file: File,
        public onCompleted: (fileData: string) => void,
        public onProgressChanged?: (progress: number) => void,
        public sliceSize: number = 16384
    ) { }

    public startReading(): void {
        if (!this.file) {
            return;
        }

        const encodeType = 'GB2312';

        this.chunkDatas = [];

        const reader = new FileReader();
        const fileSize = this.file.size;
        let progress = 0;
        let offset = 0;
        let blob: Blob;

        reader.onloadend = (e: ProgressEvent) => {
            if ((e.target as FileReader).readyState === FileReader.DONE) {
                const chunk = (e.target as FileReader).result;
                if (typeof chunk === 'string') {
                    this.chunkDatas.push(chunk);
                }

                progress = (offset / fileSize) * 100;

                if (offset < fileSize) {
                    offset += this.sliceSize;
                    blob = this.file.slice(offset, offset + this.sliceSize);
                    reader.readAsText(blob, encodeType);
                } else {
                    progress = 100;
                    if (this.onCompleted) {
                        this.onCompleted(this.chunkDatas.join(''));
                    }
                }

                if (this.onProgressChanged) {
                    this.onProgressChanged(Math.round(progress));
                }
            }
        };

        if (this.onProgressChanged) {
            this.onProgressChanged(progress);
        }

        blob = this.file.slice(offset, offset + this.sliceSize);
        reader.readAsText(blob, encodeType);
    }
}

export class WebFileWriter {
    public static writeFile(fileName: string, textContent: string) {
        const blob = new Blob([textContent], { type: 'text/plain' });
        if (window.navigator.msSaveOrOpenBlob) {
            window.navigator.msSaveBlob(blob, fileName);
        } else {
            const doc = window.document;
            const elem = doc.createElement('a');
            elem.href = window.URL.createObjectURL(blob);
            elem.download = fileName;

            doc.body.appendChild(elem);
            elem.click(); // click the <a/> element to fire the download action
            doc.body.removeChild(elem);
        }
    }
}

export function OpenFileSelectDialog(
    onFileChanged: (selectedFile: File) => void,
    acceptFileType: string
): void {
    const fileInputElemId = '_fileInputElem_';

    const doc = window.document;
    let elem = doc.getElementById(fileInputElemId) as HTMLInputElement;
    if (!elem) {
        elem = doc.createElement('input');
        elem.setAttribute('id', fileInputElemId);
        elem.setAttribute('type', 'file');
        elem.setAttribute('accept', acceptFileType);
        elem.setAttribute('style', 'display:none');
        elem.onchange = () => {
            const file = elem.files![0];
            if (file && onFileChanged) {
                onFileChanged(file);
            }
        };
        doc.body.appendChild(elem);
    }

    elem.click();
    // doc.body.removeChild(elem);
}
